// MvxBindingDescription.cs
// (c) Copyright Cirrious Ltd. http://www.cirrious.com
// MvvmCross is licensed using Microsoft Public License (Ms-PL)
// Contributions and inspirations noted in readme.md and license.txt
// 
// Project Lead - Stuart Lodge, @slodge, me@slodge.com

//using Cirrious.MvvmCross.Interfaces.Converters;

using System.Text;
using T4UtilityBelt.Serializers;
using T4UtilityBelt.UxDesigns.Bindings.Parser.Parse;

namespace T4UtilityBelt.UxDesigns.Bindings
{
    public class Binding : IXAttributeSerializer
    {
        private static MvxSwissBindingParser Parser = new MvxSwissBindingParser();

        public Binding()
        {
        }

        public Binding(string sourcePropertyPath)
        {
            SourcePropertyPath = sourcePropertyPath;
        }

        public Binding(string targetName, string sourcePropertyPath, string converter,
                       object converterParameter, object fallbackValue, BindingMode mode)
        {
            TargetName = targetName;
            SourcePropertyPath = sourcePropertyPath;
            Converter = converter;
            ConverterParameter = converterParameter;
            FallbackValue = fallbackValue;
            Mode = mode;
        }

        public Binding(string propertyName, BindingMode bindingMode)
        {
            this.SourcePropertyPath = propertyName;
            this.Mode = bindingMode;
        }

        public string TargetName { get; set; }
        public string SourcePropertyPath { get; set; }
        public string Converter { get; set; }
        public object ConverterParameter { get; set; }
        public object FallbackValue { get; set; }
        public BindingMode Mode { get; set; }

        public override string ToString()
        {
            return string.Format("from {0} to {1}", SourcePropertyPath, TargetName);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.EndsWith(System.String)"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", MessageId = "System.String.StartsWith(System.String)")]
        public static implicit operator Binding(string value)
        {
            Binding binding;
            if (value != null
                && value.StartsWith("{")
                && value.EndsWith("}")
                && Parser.TryParseBindingDescription(value.Substring(2, value.Length - 2), out binding))
            {
                return binding;
            }
            return new Binding(value);
        }


        public string Serialize()
        {
            var sb = new StringBuilder();
            if (sb.Length > 0)
            {
                sb.Append("; ");
            }
            sb.Append(this.TargetName);

            if (sb.Length > 0)
            {
                sb.Append(" ");
            }
            sb.Append(this.SourcePropertyPath);

            if (!string.IsNullOrEmpty(this.Converter))
            {
                sb.Append(", Converter=");
                sb.Append(this.Converter);
                if (this.ConverterParameter != null)
                {
                    sb.Append(", ConverterParameter=");
                    sb.Append(this.ConverterParameter);
                }
            }

            if (this.FallbackValue != null)
            {
                sb.Append(", FallbackValue=");
                sb.Append(this.FallbackValue);
            }

            if (this.Mode != BindingMode.Default)
            {
                sb.Append(", Mode=");
                sb.Append(this.Mode);
            }
            return sb.ToString();
        }


        public void Deserialize(string value)
        {
            Binding binding;
            if (Parser.TryParseBindingDescription(value, out binding))
            {
                TargetName = binding.TargetName;
                SourcePropertyPath = binding.SourcePropertyPath;
                Converter = binding.Converter;
                ConverterParameter = binding.ConverterParameter;
                FallbackValue = binding.FallbackValue;
                Mode = binding.Mode;
            }
            else
            {
                throw new BindingException(string.Format("Could not parse binding: {0} ", value));
            }
            //throw new System.NotImplementedException();
        }

    }
}